/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * SettingsDialog.java
 *
 * Created on Aug 4, 2009, 4:49:59 PM
 */

package com.googlecode.mindlistening.gui;

import com.googlecode.mindlistening.PropertiesStorage;
import com.googlecode.mindlistening.SimpleAudioRecorder;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import org.apache.commons.lang.StringUtils;
import org.jdesktop.swingx.JXErrorPane;


/**
 *
 * @author ryan
 */
public class SettingsDialog extends javax.swing.JDialog {

    final private PropertiesStorage storage;
    private DefaultComboBoxModel mixerModel = new DefaultComboBoxModel();

    /** Creates new form SettingsDialog */
    public SettingsDialog(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        storage = null;
        buildMixerList();
        initComponents();
    }


    /** Creates new form SettingsDialog */
    public SettingsDialog(PropertiesStorage prop_storage, javax.swing.JDialog parent, boolean modal) {
        super(parent, modal);
        this.storage = prop_storage;
        buildMixerList();
        initComponents();
        setTitle("Mind Listning? settings...");
        addWindowListener(new java.awt.event.WindowAdapter() {
                    public void windowClosing(java.awt.event.WindowEvent e) {
                        dispose();
                    }
                });

          String selectedMixerIndex = storage.loadProperty("selectedMixerIndex");
          if (selectedMixerIndex == null) selectedMixerIndex = "default";
          mixerComboBox.setSelectedItem(selectedMixerIndex);

          String ffmpegCmd = storage.loadProperty("ffmpegcmd");
          if (StringUtils.isNotEmpty(ffmpegCmd)) {
              ffmpegTextField.setBackground(Color.YELLOW);
              ffmpegTextField.setText(ffmpegCmd);
          } else {
              ffmpegTextField.setBackground(Color.WHITE);
          }
         String bitrate = storage.loadProperty("bitrate");
         if (bitrate == null) bitrate = "24";
         bitrateComboBox.setSelectedItem(bitrate);

         String frequency = storage.loadProperty("frequency");
         if (frequency == null) frequency = "24000";
         frequencyComboBox.setSelectedItem(frequency);

         ffmpegEditorPane.addHyperlinkListener(new HyperlinkListener() {

            @Override
            public void hyperlinkUpdate(HyperlinkEvent hle) {
                if (HyperlinkEvent.EventType.ACTIVATED.equals(hle.getEventType())) {
                    storage.showURL("http://lame.buanzo.com.ar/");
                }
            }
        });

        try {
            Integer tagStartOffset = Integer.parseInt(storage.loadProperty("tagStartOffset"));
            tagStartOffsetSpinner.setValue(tagStartOffset);
        } catch (Exception e) { // ignore
        }
        try {
            Integer tagDuration = Integer.parseInt(storage.loadProperty("tagDuration"));
            tagDurationSpinner.setValue(tagDuration);
        } catch (Exception e) { // ignore
        }

    }

    private void buildMixerList() {
        mixerModel.addElement("default");
        mixerModel.addElement("last");
        List<String> mixers = SimpleAudioRecorder.dumpMixers();
        for (String mixer : mixers) {
            mixerModel.addElement(mixer);
        }
    }

    public ComboBoxModel getMixerModel() {
        return mixerModel;
    }


    private boolean acceptable(String bitrate, String frequency) {
        long br = Long.parseLong(bitrate);
        long fq = Long.parseLong(frequency);
        if (fq == 44100 && br >= 48) return true;
        if (fq == 11025 && br <= 20) return true;
        if (fq == 22050) {
            long[] valid = {24,32,40,48,56};
            if (Arrays.binarySearch(valid, br) >=0 ) return true;
        }
        return false;
    }
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        okButton = new javax.swing.JButton();
        cancelButton = new javax.swing.JButton();
        mixerComboBox = new javax.swing.JComboBox();
        jLabel6 = new javax.swing.JLabel();
        jScrollPane2 = new javax.swing.JScrollPane();
        mixerInfoEditorPane = new javax.swing.JEditorPane();
        jLabel7 = new javax.swing.JLabel();
        jLabel8 = new javax.swing.JLabel();
        jLabel9 = new javax.swing.JLabel();
        jLabel10 = new javax.swing.JLabel();
        tagStartOffsetSpinner = new javax.swing.JSpinner();
        tagDurationSpinner = new javax.swing.JSpinner();
        jPanel1 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        ffmpegTextField = new javax.swing.JTextField();
        jScrollPane1 = new javax.swing.JScrollPane();
        ffmpegEditorPane = new javax.swing.JEditorPane();
        bitrateComboBox = new javax.swing.JComboBox();
        jLabel2 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        frequencyComboBox = new javax.swing.JComboBox();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

        okButton.setText("OK");
        okButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                okButtonActionPerformed(evt);
            }
        });

        cancelButton.setText("Cancel");
        cancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelButtonActionPerformed(evt);
            }
        });

        mixerComboBox.setModel(getMixerModel());
        mixerComboBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mixerComboBoxActionPerformed(evt);
            }
        });

        jLabel6.setText("Audio Source");

        mixerInfoEditorPane.setEditable(false);
        jScrollPane2.setViewportView(mixerInfoEditorPane);

        jLabel7.setText("Node Audio Offset");

        jLabel8.setText("- seconds");

        jLabel9.setText("Node Audio Duration");

        jLabel10.setText("seconds");

        tagStartOffsetSpinner.setModel(new javax.swing.SpinnerNumberModel(Integer.valueOf(10), Integer.valueOf(0), null, Integer.valueOf(1)));

        tagDurationSpinner.setModel(new javax.swing.SpinnerNumberModel(Integer.valueOf(20), Integer.valueOf(0), null, Integer.valueOf(1)));

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("mp3 conversion"));

        jLabel1.setText("ffmpeg");

        ffmpegTextField.setText("C:\\Program Files\\FFmpeg for Audacity\\ffmpeg.exe");

        jScrollPane1.setBorder(null);

        ffmpegEditorPane.setBackground(javax.swing.UIManager.getDefaults().getColor("Panel.background"));
        ffmpegEditorPane.setBorder(null);
        ffmpegEditorPane.setContentType("text/html");
        ffmpegEditorPane.setEditable(false);
        ffmpegEditorPane.setText("<html>\r\n  <head>\r\n\r\n  </head>\r\n  <body>\r\n    Enter the full path to ffmpeg above.                           Need ffmpeg? Get it <a href=\"\">here</a>\n  </body>\r\n</html>\r\n");
        jScrollPane1.setViewportView(ffmpegEditorPane);

        bitrateComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "128", "112", "96", "80", "64", "56", "48", "40", "32", "24", "20", "18", "16", "8" }));
        bitrateComboBox.setSelectedIndex(6);

        jLabel2.setText("bitrate");

        jLabel4.setText("frequency");

        jLabel5.setText("Hz");

        jLabel3.setText("kbps");

        frequencyComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "44100", "22050", "11025" }));
        frequencyComboBox.setSelectedIndex(1);

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGap(14, 14, 14)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(jLabel2)
                            .addComponent(jLabel4))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(frequencyComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(bitrateComboBox, 0, 89, Short.MAX_VALUE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel5)
                            .addComponent(jLabel3))
                        .addGap(24, 24, 24))
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addGap(18, 18, 18)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 362, Short.MAX_VALUE)
                            .addComponent(ffmpegTextField))))
                .addContainerGap(33, Short.MAX_VALUE))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(ffmpegTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel1))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(bitrateComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel3))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel4)
                    .addComponent(jLabel5)
                    .addComponent(frequencyComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap(363, Short.MAX_VALUE)
                        .addComponent(cancelButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(okButton))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(23, 23, 23)
                        .addComponent(jLabel6)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 395, Short.MAX_VALUE)
                            .addComponent(mixerComboBox, 0, 395, Short.MAX_VALUE)))
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(jLabel9)
                            .addComponent(jLabel7))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(tagDurationSpinner)
                            .addComponent(tagStartOffsetSpinner, javax.swing.GroupLayout.DEFAULT_SIZE, 51, Short.MAX_VALUE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(jLabel10, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(jLabel8, javax.swing.GroupLayout.DEFAULT_SIZE, 69, Short.MAX_VALUE)))
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(mixerComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel6))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 55, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel7)
                    .addComponent(tagStartOffsetSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel8))
                .addGap(6, 6, 6)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel9)
                    .addComponent(tagDurationSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel10))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(okButton)
                    .addComponent(cancelButton))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
        storage.storeProperty("ffmpegcmd", ffmpegTextField.getText());
        String selectedMixerIndex = (String) mixerComboBox.getSelectedItem();
        storage.storeProperty("selectedMixerIndex", selectedMixerIndex);

        Integer tagStartOffset = (Integer) tagStartOffsetSpinner.getValue();
        storage.storeProperty("tagStartOffset", tagStartOffset.toString());

        Integer tagDuration = (Integer) tagDurationSpinner.getValue();
        storage.storeProperty("tagDuration", tagDuration.toString());

        String bitrate = (String) bitrateComboBox.getSelectedItem();
        String frequency = (String) frequencyComboBox.getSelectedItem();
        if (acceptable(bitrate, frequency)) {
            storage.storeProperty("bitrate", bitrate);
            storage.storeProperty("frequency", frequency);
             dispose();
        }
        else JXErrorPane.showFrame(new IllegalArgumentException("The bitrate and frequency settings cant work together for flash."));       
}//GEN-LAST:event_okButtonActionPerformed

    private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
        dispose();
    }//GEN-LAST:event_cancelButtonActionPerformed

    private void mixerComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mixerComboBoxActionPerformed
        String selectedMixerIndex = "default";
        int index = mixerComboBox.getSelectedIndex();
        if (index == 1) selectedMixerIndex = "last";
        if (index > 1) {
            index = index - 2;
            selectedMixerIndex = index + "";
        }
        String lineInfo = SimpleAudioRecorder.dumpLineInfo(selectedMixerIndex);
        mixerInfoEditorPane.setText(lineInfo);
    }//GEN-LAST:event_mixerComboBoxActionPerformed

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                SettingsDialog dialog = new SettingsDialog(new javax.swing.JFrame(), true);
                dialog.addWindowListener(new java.awt.event.WindowAdapter() {
                    public void windowClosing(java.awt.event.WindowEvent e) {
                        System.exit(0);
                    }
                });
                dialog.setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JComboBox bitrateComboBox;
    private javax.swing.JButton cancelButton;
    private javax.swing.JEditorPane ffmpegEditorPane;
    private javax.swing.JTextField ffmpegTextField;
    private javax.swing.JComboBox frequencyComboBox;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JComboBox mixerComboBox;
    private javax.swing.JEditorPane mixerInfoEditorPane;
    private javax.swing.JButton okButton;
    private javax.swing.JSpinner tagDurationSpinner;
    private javax.swing.JSpinner tagStartOffsetSpinner;
    // End of variables declaration//GEN-END:variables

}
